package com.gzhryc.shared_device.oem.code.device;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.common.redis.RedisTools;
import com.gzhryc.common.secruity.EncryptTools;
import com.gzhryc.shared_device.bxscn.code.IBXSCNCacheManager;
import com.gzhryc.shared_device.bxscn.code.dao.db.PortableEnergyCabinet;
import com.gzhryc.shared_device.bxscn.code.dao.db.PortableEnergyCabinetSlot;
import com.gzhryc.shared_device.oem.code.RedisDBConstants;

import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class BXSCNCacheManager implements IBXSCNCacheManager {

    static Logger log = Logger.getLogger(BXSCNCacheManager.class);

    static BXSCNCacheManager me;

    public static BXSCNCacheManager self(){
        if(me == null){
            me = new BXSCNCacheManager();
        }
        return me;
    }

    @Override
    public PortableEnergyCabinet getPortableEnergyCabinet(String deviceSn) {
        if(StringTools.isNotBlank(deviceSn)) {
            String json = RedisTools.get().get(RedisDBConstants.BXSCN_DEVICE_DB, deviceSn);
            if (JsonTools.isJsonStr(json)) {
                return JsonTools.fromJson(json, PortableEnergyCabinet.class);
            }
        }
        return null;
    }

    @Override
    public void savePortableEnergyCabinet(PortableEnergyCabinet portableEnergyCabinet) {
        if(portableEnergyCabinet != null && StringTools.isNotBlank(portableEnergyCabinet.getDeviceSn())) {
            RedisTools.get().set(RedisDBConstants.BXSCN_DEVICE_DB, portableEnergyCabinet.getDeviceSn(), JsonTools.toJson(portableEnergyCabinet));
        }
    }

    @Override
    public void removeBatteryCabinet(String deviceSn) {
        if(StringTools.isNotBlank(deviceSn)) {
            RedisTools.get().delete(RedisDBConstants.BXSCN_DEVICE_DB,deviceSn);
            //移除所有卡槽信息
            removePortableEnergyCabinet(deviceSn);
        }
    }

    @Override
    public PortableEnergyCabinetSlot getPortableEnergyCabinetSlot(String deviceSn, Integer slotNum) {
        if(StringTools.isNotBlank(deviceSn) && slotNum != null){
            String key = deviceSn + "_" + slotNum;
            String json = RedisTools.get().get(RedisDBConstants.BXSCN_DEVICE_SLOT_DB, key);
            if (JsonTools.isJsonStr(json)) {
                return JsonTools.fromJson(json, PortableEnergyCabinetSlot.class);
            }
        }
        return null;
    }

    public List<PortableEnergyCabinetSlot> findPortableEnergyCabinetSlot(String deviceSn) {
        if (StringTools.isNotBlank(deviceSn)) {
            String key = deviceSn + "_*";
            Set<String> keys = RedisTools.get().findKeys(RedisDBConstants.BXSCN_DEVICE_SLOT_DB, key);
            if (keys != null && keys.size() > 0) {
                List<PortableEnergyCabinetSlot> result = new ArrayList<>();
                for (String cc : keys) {
                    String json = RedisTools.get().get(RedisDBConstants.BXSCN_DEVICE_SLOT_DB, cc);
                    if (JsonTools.isJsonStr(json)) {
                        result.add(JsonTools.fromJson(json, PortableEnergyCabinetSlot.class));
                    }
                }
                return result;
            }
        }
        return null;
    }

    @Override
    public void savePortableEnergyCabinetSlot(PortableEnergyCabinetSlot portableEnergyCabinetSlot) {
        if(portableEnergyCabinetSlot != null && StringTools.isNotBlank(portableEnergyCabinetSlot.getDeviceSn()) && portableEnergyCabinetSlot.getSlotNum() != null) {
            String key = portableEnergyCabinetSlot.getDeviceSn() + "_" + portableEnergyCabinetSlot.getSlotNum();
            RedisTools.get().set(RedisDBConstants.BXSCN_DEVICE_SLOT_DB, key, JsonTools.toJson(portableEnergyCabinetSlot));
        }
    }

    @Override
    public void removePortableEnergyCabinetSlot(String deviceSn, Integer slotNum) {
        if (StringTools.isNotBlank(deviceSn) && slotNum != null) {
            String key = deviceSn + "_" + slotNum;
            RedisTools.get().delete(RedisDBConstants.BXSCN_DEVICE_SLOT_DB, key);
        }
    }

    @Override
    public void removePortableEnergyCabinet(String deviceSn) {
        if(StringTools.isNotBlank(deviceSn)) {
            Jedis jedis = RedisTools.get().getJedis();
            if(jedis != null) {
                try {
                    jedis.select(RedisDBConstants.BXSCN_DEVICE_SLOT_DB);
                    Set<String> keys = jedis.keys(deviceSn + "_\\d+");
                    if (keys != null && keys.size() > 0) {
                        for (String key : keys) {
                            jedis.del(key);
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                } finally {
                    jedis.close();
                }
            }
        }
    }

    @Override
    public List<PortableEnergyCabinet> findBXSCNDevice() {
        Jedis jedis = RedisTools.get().getJedis();
        if (jedis != null) {
            try {
                List<PortableEnergyCabinet> deviceList = new ArrayList<>();
                jedis.select(RedisDBConstants.BXSCN_DEVICE_DB);
                String cursor = ScanParams.SCAN_POINTER_START;
                do {
                    ScanResult<String> result = jedis.scan(cursor);
                    if (result == null)
                        break;
                    cursor = result.getCursor();
                    if (result != null && result.getResult() != null) {
                        for (String key : result.getResult()) {
                            String obj = jedis.get(key);
                            if (StringUtils.isNoneBlank(obj)) {
                                deviceList.add(JsonTools.fromJson(obj, PortableEnergyCabinet.class));
                            }
                        }
                    }
                } while (!cursor.equals(ScanParams.SCAN_POINTER_START));
                return deviceList;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                jedis.close();
            }
        }
        return null;
    }

    public List<PortableEnergyCabinetSlot> findBXSCNSlotDevice() {
        Jedis jedis = RedisTools.get().getJedis();
        if (jedis != null) {
            try {
                List<PortableEnergyCabinetSlot> deviceList = new ArrayList<>();
                jedis.select(RedisDBConstants.BXSCN_DEVICE_SLOT_DB);
                String cursor = ScanParams.SCAN_POINTER_START;
                do {
                    ScanResult<String> result = jedis.scan(cursor);
                    if (result == null)
                        break;
                    cursor = result.getCursor();
                    if (result != null && result.getResult() != null) {
                        for (String key : result.getResult()) {
                            String obj = jedis.get(key);
                            if (StringUtils.isNoneBlank(obj)) {
                                deviceList.add(JsonTools.fromJson(obj, PortableEnergyCabinetSlot.class));
                            }
                        }
                    }
                } while (!cursor.equals(ScanParams.SCAN_POINTER_START));
                return deviceList;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                jedis.close();
            }
        }
        return null;
    }


    @Override
    public void setCommandResult(String deviceSn, String messageId, String content) {
        if(StringTools.isNotBlank(deviceSn) && StringTools.isNotBlank(messageId) && StringTools.isNotBlank(content)) {
            String key = EncryptTools.md5(deviceSn + "_" + messageId);
            RedisTools.get().set(RedisDBConstants.DEVICE_COMMAND_CACHE_DB, key, content,30L);
            log.info("设置KEY = {{0}}，CONTENT = {{1}}",key,content);
        }
    }

    @Override
    public <T> T getCommandResult(String deviceSn,String messageId, Class<T> clazz) {
        if(StringTools.isNotBlank(deviceSn) && StringTools.isNotBlank(messageId) && clazz != null) {
            String key = EncryptTools.md5(deviceSn + "_" + messageId);
            String content = RedisTools.get().get(RedisDBConstants.DEVICE_COMMAND_CACHE_DB, key);
            log.info("获取KEY = {{0}}，CONTENT = {{1}}",key,content);
            if (StringTools.isNotBlank(content)) {
                return JsonTools.fromJson(content, clazz);
            }
        }
        return null;
    }
}
